/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package avl.sv.shared.model.classifier;

import avl.sv.shared.LDA;
import avl.sv.shared.Sample;
import avl.sv.shared.SampleSetClass;
import avl.sv.shared.model.featureGenerator.AbstractFeatureGenerator;
import avl.sv.shared.model.featureGenerator.FeatureGeneratorOptionsPromptInterface;
import java.util.ArrayList;
import java.util.Date;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.colorchooser.AbstractColorChooserPanel;

/**
 *
 * @author benbryan
 */
public class ClassifierLDA implements AbstractClassifier {

    LDA lda = null;
    double labels[];
    
    public String classNames[];
    public boolean isActive = true;
    public String message;
    public Date lastTrained;
    @Override
    public String[] getClassNames() {
        return classNames;
    }

    @Override
    public void setClassNames(String[] classNames) {
        this.classNames = classNames;
    }

    @Override
    public boolean isActive() {
        return isActive;
    }

    @Override
    public void setActive(boolean isActive) {
        this.isActive = isActive;
    }

    @Override
    public String getMessage() {
        return message;
    }

    @Override
    public void setMessage(String message) {
        this.message = message;
    }

    @Override
    public Date getLastTrained() {
        return lastTrained;
    }

    @Override
    public void setLastTrained(Date lastTrained) {
        this.lastTrained = lastTrained;
    }
    
    @Override
    public void train(ArrayList<SampleSetClass> samplesSets) {
        try {
            //Collect all samples and labels 
            double features[][] = new double[numelSamples(samplesSets)][];
            int label[] = new int[numelSamples(samplesSets)];
            int sampleIdx = 0;
            for (int setIdx = 0; setIdx < samplesSets.size(); setIdx++) {
                SampleSetClass sampleSet = samplesSets.get(setIdx);
                for (Sample sample : sampleSet.samples) {
                    features[sampleIdx] = sample.featureVector;
                    label[sampleIdx] = setIdx;
                    sampleIdx++;
                }
            }
            
            lda = new LDA(features, label, true);
            
            int numelClasses = samplesSets.size();
            labels = new double[samplesSets.size()];
            classNames = new String[numelClasses];
            for (int setIdx = 0; setIdx < samplesSets.size(); setIdx++) {
                labels[setIdx] = setIdx;
                classNames[setIdx] = samplesSets.get(setIdx).className;
            }
            
            lastTrained = new Date();
            message = "LDA classifier generated";
        } catch (Exception ex) {
            System.out.println(ex);
            message = "Failed to train LDA";
        }
    }

    private int numelSamples(ArrayList<SampleSetClass> samplesSets){
        int count = 0;
        for (SampleSetClass sampleSet:samplesSets){
            count += sampleSet.samples.size();
        }
        return count;
    }

    @Override
    public boolean isValid() {
        return lda!=null;
    }

    @Override
    public void predict(ArrayList<Sample> samples) {
        for (Sample sample:samples){
            sample.classifierLabel = lda.predict(sample.featureVector);
        }            
    }

    @Override
    public double[] getLabels() {
        return labels;
    }

    @Override
    public void invalidate() {
        lda = null;
    }

    private class OptionsPrompt extends JPanel implements ClassifierOptionsPromptInterface{

        public OptionsPrompt() {
            JLabel label = new JLabel("No Options");
            add(label);
            label.setVisible(true);
        }
        
        @Override
        public AbstractClassifier getClassifier() {
            return new ClassifierLDA();
        }
        @Override
        public void setNumelFeatures(int numel) {
        }
    }
    @Override
    public JPanel getOptionsPanel() {
        return new OptionsPrompt();
    }

    @Override
    public String getName() {
        return "LDA";
    }
}
